home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Utilities
/
InstallerMaker™
/
InstallerMaker__2.0.2_Installe
/
InstallerMaker™ 2.0.2 Installer
/
InstallerMaker Extensions
/
IMid Extension
/
IMid.p
< prev
next >
Wrap
Text File
|
1994-05-03
|
8KB
|
255 lines
(* ****************************************************************
IMid.p Translated to MPW Pascal by Jim Merritt (jam)
based on an original C routine by Raymond Lau.
Copyright © 1993 Aladdin Systems, Inc. & Raymond Lau.
All Rights Reserved.
In combination with the associated make file (IMid.make),
this source text produces an IMid installer extension, which
can be called by a Product Installer during the installation
process. Specifications for IBeg, IMid, ICnd, and IEnd
installer extensions are given in the documentation for
StuffIt InstallerMaker™.
In the absence of the folder manager (typically on System 6),
this subroutine will:
• Put any Aladdin folder within the :System:Extensions folder,
creating the Extensions folder if necessary.
• Put any file of types 'appe' or 'thng' into the
:System:Extensions folder, creating the Extensions folder if
necessary.
• Put files of type 'Pref' and 'pref' into the :System:Preferences
folder, creating the Preferences folder if necessary.
CHANGE HISTORY:
VER DATE ENGR DESCRIPTION
1 93.06.08 jam Initial version, based on Lau's
original in C.
2 93.06.16 jam Pascal definitions of code resources were
changed to replace BOOLEAN parameters and
function return values with INTEGERs, and
also to replace enumeration types and SETs
with INTEGERs. This was made necessary
when we discovered that certain Pascal
compilers used very eccentric enumeration
mechanisms, which were profoundly
incompatible with the original C definitions
at the machine-code level. The best
compromise was to fall back to INTEGERs.
3 93.06.17 jam Introduced and made slight modifications to
mag's routine, BlessedFldrSpec, replacing
rl's original GetSysVolDir routine (from C
version). Customers should compare
GetSysVolDir and BlessedFolderSpec to see
differences between low-level and higher-
level coding to achieve the same ends.
Rewrote code to change ensure that sense of
FindFolderInSystem is always positive logic.
4 93.06.28 jam Changed to support 'thng' file type, per
changes to Lau’s C version.
5 94.03.14 jam Changed DoWhileInstalling to support new
"packages" parameter.
6 94.05.03 jam Changed DoWhileInstalling to support new
"after" parameter.
****************************************************************** *)
(*$Z+*) (* Allows linker to find DoWhileInstalling without declaring it
in the interface *)
UNIT IMid;
INTERFACE (* empty -- see $Z directive, above *)
IMPLEMENTATION
(* Putting a subroutine within a UNIT that has an empty
IMPLEMENTATION is an oft-used method for creating
a standalone code-resource in MPW Pascal.
*)
(* *********************** INCLUDES *************************** *)
USES Types,
ToolUtils, (* for BitAnd *)
Folders,
OSUtils, (* for EqualString *)
Files, (* for HParamBlockRec *)
GestaltEqu (* for Gestalt *);
CONST
EmptyString= '';
(* For using INTEGERs as if they were BOOLEANs *)
IntFALSE= 0;
IntTRUE= 1; (* (x <> IntFALSE) should be used to test for IntTRUE *)
(* Use the constant IntTRUE only when you desire to assign a TRUE
value to an INTEGER.
*)
(* Return and parameter values for various INTEGER items *)
(* For ICnd, IMid *)
OKToContinue= 0; (* For ICnd, IMid *)
SkipThisItem= 1; (* For ICnd, IMid *)
CancelInstallation= 2; (* For IMid only *)
(* For IBeg, IEnd *)
WasNOTAborted= 0;
WasAborted= 1;
(* FindFolderInSystem must be FORWARD because DoWhileInstalling MUST
be the first routine that has a code body.
*)
FUNCTION FindFolderInSystem(name: str255; VAR vol: INTEGER;
VAR dir: LongInt): BOOLEAN; FORWARD;
FUNCTION DoWhileInstalling( userVol: INTEGER;
userDir: LongInt;
VAR destVol: INTEGER;
VAR destDir: LongInt;
isFolder: INTEGER;
VAR name: Str255;
creationDate: LongInt;
modificationDate: LongInt;
ftype, fcreator: OSType;
packages: INTEGER;
after: INTEGER): INTEGER;
VAR
gest: LongInt;
result: INTEGER;
BEGIN (* DoWhileInstalling *)
result := OKToContinue;
IF (after = IntFALSE) THEN BEGIN (* Only execute this BEFORE the file
is installed. *)
(* IF FindFolder is present THEN ... *)
IF (Gestalt(gestaltFindFolderAttr,gest) <> noErr) (* does gestalt exist? *)
THEN IF (NOT (BAND(gest,BitShift(1, gestaltFindFolderPresent)) <> 0))
(* is the FindFolder avail bit set? *)
THEN BEGIN
IF (isFolder <> IntFALSE) THEN BEGIN
IF (EqualString(name,'Aladdin',FALSE,TRUE)) THEN
BEGIN
IF (NOT FindFolderInSystem('Extensions', destVol, destDir))
THEN result := CancelInstallation;
(* If FindFolderInSystem succeeds, it changes destVol and
destDir, thus redirecting the item under consideration
to the specified folder. (In other words, the IMid
changes the destination path before the Product
Installer writes the item to the target.)
*)
END
END ELSE BEGIN
IF ((ftype = 'appe') OR (ftype = 'thng')) THEN BEGIN
IF (NOT FindFolderInSystem('Extensions',destVol,destDir))
THEN result := CancelInstallation;
END ELSE IF ((ftype = 'Pref') OR (ftype = 'pref')) THEN BEGIN
IF (NOT FindFolderInSystem('Preferences',destVol,destDir))
THEN result := CancelInstallation;
END;
END;
END;
END (* Guard to make sure we are executing
before the file is installed. *);
DoWhileInstalling := result;
END (* DoWhileInstalling *);
FUNCTION BlessedFldrSpec ( VAR vRefNum: integer; VAR dirID: longint;
VAR name: Str255 ): OSErr;
(* Should take every possible way of finding the blessed folder.
On ENTRY, values of vRefNum, dirID, and name are undefined.
On EXIT,
A return code of noErr, means that vRefNum, dirID and name
contain a complete path specification for the blessed
folder (not necessarily named 'System'!).
Any other return code leaves the contents of vRefNum, dirID, and
name undefined, and possibly altered from their entry states.
*)
CONST
kSync= FALSE; (* call File System synchronously *)
VAR
theWorld: SysEnvRec;
error: OSErr;
wdpb: WDPBRec;
cipb: CInfoPBRec;
BEGIN (* BlessedFldrSpec *)
name := EmptyString;
vRefNum := 0;
dirID := 0;
error := SysEnvirons(1,theWorld);
(* prepare wdpb for PBGetWDInfo *)
wdpb.ioCompletion := NIL;
wdpb.ioVRefNum := theWorld.sysVRefNum;
wdpb.ioWDIndex := 0; (* use ioVRefNum *)
wdpb.ioWDProcID := 0;
wdpb.ioWDVRefNum := 0;
wdpb.ioNamePtr := NIL; (* be clean about it *)
wdpb.ioWDDirID := 0;
wdpb.ioResult := noErr;
error := PBGetWDInfo(@wdpb, FALSE);
if (error = noErr)
THEN BEGIN
vRefNum := wdpb.ioWDVRefNum;
dirID := wdpb.ioWDDirID;
(* fill cipb for PBGetCatInfo *)
cipb.ioCompletion := NIL;
cipb.ioNamePtr := @name; (* File System fills this in *)
cipb.ioVRefNum := vRefNum;
cipb.ioFDirIndex := -1; (* get name using vRefNum, dirID *)
cipb.ioDirID := dirID;
error := PBGetCatInfo(@cipb, kSync);
if (error <> noErr) THEN name := EmptyString;
END;
BlessedFldrSpec := error;
END (* BlessedFldrSpec *);
FUNCTION FindFolderInSystem(* name: str255; VAR vol: INTEGER;
VAR dir: LongInt): BOOLEAN *);
(* On ENTRY, if the specified system subfolder does not
exist, routine attempts to create it.
On EXIT, returns TRUE if the specified system subfolder
exists, and FALSE if not (even despite attempts at
creation). When TRUE, vol and dir specify the folder.
*)
VAR
sysvol: INTEGER;
sysdir: LongInt;
HRec: HParamBlockRec;
FFISname: Str255;
FFISError: OSErr;
BEGIN (* FindFolderInSystem *)
FFISError := BlessedFldrSpec(sysvol, sysdir, FFISname);
IF (FFISError <> noErr)
THEN BEGIN FindFolderInSystem := FALSE
END ELSE BEGIN
HRec.ioNamePtr := @name;
HRec.ioVRefNum := sysvol;
HRec.ioDirID := sysdir;
IF (PBDirCreateSync(@HRec) <> noErr) THEN BEGIN
FindFolderInSystem := FALSE;
END ELSE BEGIN
vol := sysvol;
dir := HRec.ioDirID;
FindFolderInSystem := TRUE;
END;
END (* IF-THEN-ELSE *);
END (* FindFolderInSystem *);
END (* IMid *).